﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Gin.Commands;
using System.Runtime;
using System.IO;

namespace Gin
{
    public class PackageBuilder
    {

        public const string MAIN_PACKAGE_FILENAME = @"package.xml";
        public const string PACKAGE_FILE_EXTENSION = @".gin";
        public const string PACKAGE_CONTENT_FILE_EXTENSION = @".cnt";
        public const string PACKAGE_CONTENT_TEMPLATE_PATH = "%PACKAGE_CONTENT%";

        PackageBody _body;
        PackageContent _content;


        public PackageBuilder(PackageBody body)
        {
            _content = new PackageContent();
            _body = body;
        }

        public void SaveResult(string filePath)
        {
            ProcessIncludedFiles(_body.Command);

            string xmlFilePath = Path.GetTempFileName();
            GinSerializer.Serialize(_body, xmlFilePath);
            _content.AddContent(xmlFilePath, MAIN_PACKAGE_FILENAME);
            _content.SaveAs(filePath);
        }

        private void ProcessIncludedFiles(Command command)
        {
            if (command is IContainerCommand)
            {
                IContainerCommand iContainer = (IContainerCommand)command;
                foreach (Command cmd in iContainer.InnerCommands)
                {
                    ProcessIncludedFiles(cmd);
                }
            }

            if (command is IContentCommand)
            {
                IContentCommand cntCommand = (IContentCommand)command;
                string sourceFilePath = cntCommand.ContentPath;
                if (!_content.ContainFilePath(sourceFilePath))
                {
                    string destFileName = GetGuidContentFileName();
                    _content.AddContent(sourceFilePath, destFileName);
                    cntCommand.ContentPath = Path.Combine(PACKAGE_CONTENT_TEMPLATE_PATH, destFileName);
                }
                else
                {
                    string destFileName = _content.GetFileName(sourceFilePath);
                    cntCommand.ContentPath = Path.Combine(PACKAGE_CONTENT_TEMPLATE_PATH, destFileName);
                }
            }
        }

        private string GetGuidContentFileName()
        {
            return Guid.NewGuid().ToString("N") + PACKAGE_CONTENT_FILE_EXTENSION;
        }
    }
}
